/*!
 * \file util_test.cc
 *
 * \brief Tests for the IEGen utilities
 *
 * \date Started: 9/13/10
 * \date Last Modified: 9/13/10
 * \authors Alan LaMielle
 *
 * Copyright (c) 2010, Colorado State University <br>
 * All rights reserved. <br>
 * See ../../COPYING for details. <br>
 */

#include <iegenlib/iegenlib.h>

#include <gtest/gtest.h>

using iegenlib::ParseException;
using iegenlib::EntityNotFound;
using iegenlib::EntityExists;
using iegenlib::UnionException;
using iegenlib::ComposeException;
using iegenlib::OperatorEqualsException;
using iegenlib::createUniqueName;
using iegenlib::createUniqueNames;

// TODO: Test the StringException and ParseException classes and any other util classes/routines
TEST(UtilTests, UtilTestParse){

  try{
    ParseException excep = ParseException("test");
    throw excep;
  }catch(ParseException e){
     string in = e.what();
     EXPECT_EQ(in,"test");
     return; //Success!
  }
  ADD_FAILURE()<<"ParseException exception not raised!";
}

TEST(UtilTests, UtilTestENF){

  try{
    EntityNotFound excep = EntityNotFound("test");
    throw excep;
  }catch(EntityNotFound e){
     string in = e.what();
     EXPECT_EQ(in,"test");
     return; //Success!
  }
  ADD_FAILURE()<<"EntityNotFound exception not raised!";
}

TEST(UtilTests, UtilTestEE){

  try{
    EntityExists excep = EntityExists("test");
    throw excep;
  }catch(EntityExists e){
     string in = e.what();
     EXPECT_EQ(in,"test");
     return; //Success!
  }
  ADD_FAILURE()<<"EntityExists exception not raised!";
}

TEST(UtilTests, UtilTestParse2){

  try{
    throw ParseException("test");
  }catch(ParseException e){
     string in = e.what();
     EXPECT_EQ(in,"test");
     return; //Success!
  }
  ADD_FAILURE()<<"ParseException exception not raised!";
}

TEST(UtilTests, UtilTestENF2){

  try{
    throw EntityNotFound("test");
  }catch(EntityNotFound e){
     string in = e.what();
     EXPECT_EQ(in,"test");
     return; //Success!
  }
  ADD_FAILURE()<<"EntityNotFound exception not raised!";
}

TEST(UtilTests, UtilTestEE2){

  try{
    throw EntityExists("test");
  }catch(EntityExists e){
     string in = e.what();
     EXPECT_EQ(in,"test");
     return; //Success!
  }
  ADD_FAILURE()<<"EntityExists exception not raised!";
}

TEST(UtilTests, UtilTestunion1){

  try{
    throw UnionException("test");
  }catch(UnionException e){
     string in = e.what();
     EXPECT_EQ(in,"test");
     return; //Success!
  }
  ADD_FAILURE()<<"UnionException exception not raised!";
}

TEST(UtilTests, UtilTestcompose1){

  try{
    throw ComposeException("test");
  }catch(ComposeException e){
     string in = e.what();
     EXPECT_EQ(in,"test");
     return; //Success!
  }
  ADD_FAILURE()<<"ComposeException exception not raised!";
}

TEST(UtilTests, OperatorExceptionEquals){

  try{
    throw OperatorEqualsException("test");
  }catch(OperatorEqualsException e){
     string in = e.what();
     EXPECT_EQ(in,"test");
     return; //Success!
  }
  ADD_FAILURE()<<"OperatorEqualsException exception not raised!";
}

TEST(UtilTests, UniqueNameTest){
  string name = "var";
  set<string> avoid;
  EXPECT_EQ("var", createUniqueName(name, avoid)); //Test case 1: tests to see if the name is in the set
  avoid.insert("var");
  avoid.insert("var1");
  EXPECT_EQ("var2", createUniqueName(name, avoid)); //Test case 2: tests to see if the name hits the end of the set
  avoid.insert("var3");
  EXPECT_EQ("var2", createUniqueName(name, avoid)); //Test case 3: tests to see if the name hits an open value in the middle of the set
}

TEST(UtilTests, UniqueNameListTest){
  list<string> currentNames;
  currentNames.push_back("var1");
  currentNames.push_back("var1"); //add the duplicate to make sure that the end result changes!
  currentNames.push_back("var2");
  currentNames.push_back("var3");

  map<string, string> old2new;
  set<string> symbols;

  createUniqueNames(currentNames.begin(), currentNames.end(), symbols, old2new);

  EXPECT_EQ(old2new["var1"], "var11");

}
